#ifndef __CHELPER_MEMORY_MEMORYBLOCK_H__
#define __CHELPER_MEMORY_MEMORYBLOCK_H__

#include <assert.h>
#include <iostream>
#include <unordered_map>
#include <string.h>

#include "memory/MemoryList.h"


namespace chelper {
namespace memory {

class MemoryBlock {
  public:
    MemoryBlock() : used_list_{}, free_list_(nullptr), total_(0), offset_(0) {}

    MemoryBlock(const MemoryBlock &) = delete;
    MemoryBlock &operator=(const MemoryBlock &) = delete;

    ~MemoryBlock() {
        if (free_list_ != nullptr) {
            delete free_list_;
            free_list_ = nullptr;
        }
        if (data_ != nullptr) {
            std::free(data_);
            data_ = nullptr;
        }
    }

    char *malloc(uint32_t size_t);

    void free(char *buff);

    void allocateMemory(uint64_t size_t);

    uint64_t align(uint64_t size, uint32_t bit) {
        return (size + bit - 1) &~(bit - 1);
    }

  private:
    void __allocate(uint64_t size_t);

    char *__malloc(uint64_t size_t);

    MemoryList *free_list_;
    uint64_t total_;
    uint32_t offset_;
    std::unordered_map<ChunkId, uint32_t> used_list_;
    char *data_;
};


}  // namespace memory
}  // namespace chelper

#endif  // __CHELPER_MEMORY_MEMORYBLOCK_H__